﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
using Windows.Media.Capture;
using System.Threading.Tasks;
using Windows.Storage;
using Windows.Storage.Streams;
using Windows.Graphics.Imaging;
using Windows.Graphics.Display;
using Windows.Devices.Sensors;
using Windows.UI.Xaml.Media.Imaging;
using System.IO.Compression;
using Windows.Security.Cryptography;
using Windows.Web.Http;
using System.Globalization;
using System.Collections.ObjectModel;
// “空白页”项模板在 http://go.microsoft.com/fwlink/?LinkId=391641 上有介绍

namespace HowOld
{
    /// <summary>
    /// 可用于自身或导航至 Frame 内部的空白页。
    /// </summary>
    public sealed partial class MainPage : Page
    {
        static readonly string HOW_OLD = "WP_howold" + DateTime.Now.ToString("yyyyMMdd") + ".jpg";

        private static readonly ObservableCollection<HowOldModel> howoldList = new ObservableCollection<HowOldModel>();

        public ObservableCollection<HowOldModel> HowoldList
        {
            get { return howoldList; }
        }

        StorageFolder picDir = ApplicationData.Current.LocalFolder; 
            //KnownFolders.VideosLibrary;//ApplicationData.Current.LocalFolder;

        public MainPage()
        {
            this.InitializeComponent();
            this.NavigationCacheMode = NavigationCacheMode.Required;
            DisplayInformation.AutoRotationPreferences = DisplayOrientations.Landscape;
            Frame rootFrame = Window.Current.Content as Frame;
            if (rootFrame != null)
            {
                rootFrame.ContentTransitions = null;
            }

            lv.ItemsSource = HowoldList;

            var jsonTest = "{\"AnalyticsEvent\":[  {    \"face\": {      \"age\": 27.0,      \"gender\": \"Male\"    },    \"event_datetime\": \"2015-05-09T03:43:38.621698Z\",    \"user_id\": \"5bc1102c-126b-4e40-a874-4ce6e59de5e8\",    \"session_id\": \"8ff23029-2832-42f0-862f-7e5cf41b2848\",    \"submission_method\": \"Upload\",    \"user_agent\": null,    \"location\": {      \"latitude\": 23.13,      \"longitude\": 113.24    },    \"location_city\": {      \"latitude\": 23.1,      \"longitude\": 113.2    },    \"is_mobile_device\": false,    \"browser_type\": \"Unknown\",    \"platform\": \"Unknown\",    \"mobile_device_model\": \"Unknown\"  },  {    \"face\": {      \"age\": 24.0,      \"gender\": \"Male\"    },    \"event_datetime\": \"2015-05-09T03:43:38.621698Z\",    \"user_id\": \"5bc1102c-126b-4e40-a874-4ce6e59de5e8\",    \"session_id\": \"8ff23029-2832-42f0-862f-7e5cf41b2848\",    \"submission_method\": \"Upload\",    \"user_agent\": null,    \"location\": {      \"latitude\": 23.13,      \"longitude\": 113.24    },    \"location_city\": {      \"latitude\": 23.1,      \"longitude\": 113.2    },    \"is_mobile_device\": false,    \"browser_type\": \"Unknown\",    \"platform\": \"Unknown\",    \"mobile_device_model\": \"Unknown\"  }],\"Faces\":[{\"faceId\":null,\"faceRectangle\":{\"top\":446,\"left\":1033,\"width\":611,\"height\":611},\"attributes\":{\"gender\":\"Male\",\"age\":27.0}},{\"faceId\":null,\"faceRectangle\":{\"top\":431,\"left\":2310,\"width\":585,\"height\":585},\"attributes\":{\"gender\":\"Male\",\"age\":24.0}}]}";

            //Json2Obj(jsonTest);
        }

        MediaCapture capture = null;

        bool isBusy = false;
        bool isTapped = false;
        /// <summary>
        /// 在此页将要在 Frame 中显示时进行调用。
        /// </summary>
        /// <param name="e">描述如何访问此页的事件数据。
        /// 此参数通常用于配置页。</param>
        protected async override void OnNavigatedTo(NavigationEventArgs e)
        {
            // TODO: 准备此处显示的页面。

            // TODO: 如果您的应用程序包含多个页面，请确保
            // 通过注册以下事件来处理硬件“后退”按钮:
            // Windows.Phone.UI.Input.HardwareButtons.BackPressed 事件。
            // 如果使用由某些模板提供的 NavigationHelper，
            // 则系统会为您处理该事件。

            await SetCaptureSourceAsync();
        }

        public async System.Threading.Tasks.Task SetCaptureSourceAsync()
        {
            capture = (App.Current as App).TheCapture;

            ce.Source = capture;
            await capture.StartPreviewAsync();
        }

        private async void OnTapped(object sender, TappedRoutedEventArgs e)
        {
            try
            {
                if (isBusy)
                {
                    return;
                }

                isBusy = true;
                isTapped = true;
                VoiceRecordGrid.Visibility = Windows.UI.Xaml.Visibility.Visible;
                VoiceRecording.Begin();
                await TakePhoto();
                image.Visibility = Windows.UI.Xaml.Visibility.Visible;
                image.Source = new BitmapImage(new Uri("ms-appdata:///local/" + HOW_OLD, UriKind.Absolute));
                await capture.StopPreviewAsync();

                //Windows.Storage.StorageFolder localFolder = Windows.Storage.ApplicationData.Current.LocalFolder;
                //Windows.Storage.StorageFile file = await localFolder.GetFileAsync(HOW_OLD);
                var file = await picDir.GetFileAsync(HOW_OLD);
                var rf = await FileIO.ReadBufferAsync(file);

                HttpClient http = new HttpClient();
                http.DefaultRequestHeaders.Add("Host", "how-old.net");
                http.DefaultRequestHeaders.Add("Origin", "how-old.net");
                http.DefaultRequestHeaders.Add("Referer", "http://how-old.net");
                http.DefaultRequestHeaders.Add("X-Requested-With", "With:XMLHttpRequest");

                HttpStreamContent inputStream = new HttpStreamContent(rf.AsStream().AsInputStream());
                HttpMultipartFormDataContent mul = new HttpMultipartFormDataContent("----" + DateTime.Now.ToString(CultureInfo.InvariantCulture));
                mul.Add(inputStream, "picture", "test.jpg");
                var ret = await http.PostAsync(new Uri("http://how-old.net/Home/Analyze?isTest=False", UriKind.Absolute), mul);

                if (ret.StatusCode == HttpStatusCode.Ok)
                {
                    try
                    {
                        var result = await ret.Content.ReadAsStringAsync();

                        result = result.Replace(@"\\r\\n", "").Replace(@"\\", "").Replace("\\\"[", "[").Replace("]\\\"", "]").Replace("\"{", "{").Replace("]}\"", "]}").Replace("\\", "");
                        Json2Obj(result);
                    }
                    catch (Exception ex)
                    {

                    }
                }

            }
            catch (Exception ex)
            {

            }

            VoiceRecordGrid.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
            VoiceRecording.Stop();

            isBusy = false;
        }

        private void Json2Obj(string result)
        {

            var model = Newtonsoft.Json.JsonConvert.DeserializeObject<HowOldResponse>(result);

            for (int i = 0; i < model.Faces.Length; i++)
            {
                var age = (int)model.AnalyticsEvent[i].face.age;
                var gander = model.AnalyticsEvent[i].face.gender.ToLower() == "male" ?
                    "Assets/icon-gender-male.png"
                    : "Assets/icon-gender-female.png";

                var left = model.Faces[i].faceRectangle.left / 5.1;
                var top = model.Faces[i].faceRectangle.top / 5.1;

                HowoldList.Add(new HowOldModel
                {
                    Age = age,
                    Gander = gander,
                    Margin = new Thickness(left, top, 10, 0),
                });


            }
        }

        /// <summary>
        /// 指示文件是否正在处理
        /// </summary>
        internal static bool IsProcessingPicture { get; private set; }

        //public async static Stream ZipImage(IRandomAccessStream fileStream) 
        //{
        //    BitmapDecoder decoder = await BitmapDecoder.CreateAsync(fileStream);

        //    BitmapTransform transform = new BitmapTransform()
        //    {
        //        ScaledWidth =  .Current.Bounds.Width,
        //        ScaledHeight = Windows.Current.Bounds.Width
        //    };

        //    PixelDataProvider pixelData = await decoder.GetPixelDataAsync(
        //        BitmapPixelFormat.Bgra8,
        //        BitmapAlphaMode.Straight,
        //        transform,
        //        ExifOrientationMode.IgnoreExifOrientation,
        //        ColorManagementMode.DoNotColorManage);

        //    byte[] sourcePixels = pixelData.DetachPixelData();

        //    using (Stream stream = WriteableBitmap.PixelBuffer.AsStream())
        //    {
        //        await stream.WriteAsync(sourcePixels, 0, sourcePixels.Length);
        //    }
        //}

        //static bool isBusy = false;
        //public static async Task SaveImage(string fileName, UIElement root)
        //{
        //    if (isBusy)
        //    {
        //        return;
        //    }
        //    isBusy = true;

        //    // 生成RenderTargetBitmap对象
        //    RenderTargetBitmap renderTargetBitmap = new RenderTargetBitmap();
        //    await renderTargetBitmap.RenderAsync(root);
        //    // 获取图像的二进制数据
        //    var pixelBuffer = await renderTargetBitmap.GetPixelsAsync();
        //    // 创建程序文件存储
        //    IStorageFolder applicationFolder = ApplicationData.Current.LocalFolder;
        //    IStorageFile saveFile = await applicationFolder.CreateFileAsync(fileName, CreationCollisionOption.OpenIfExists);
        //    // 把图片的二进制数据写入文件存储
        //    using (var fileStream = await saveFile.OpenAsync(FileAccessMode.ReadWrite))
        //    {
        //        var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, fileStream);
        //        encoder.SetPixelData(
        //            BitmapPixelFormat.Bgra8,
        //            BitmapAlphaMode.Ignore,
        //            (uint)renderTargetBitmap.PixelWidth,
        //            (uint)renderTargetBitmap.PixelHeight,
        //            DisplayInformation.GetForCurrentView().LogicalDpi,
        //            DisplayInformation.GetForCurrentView().LogicalDpi,
        //            pixelBuffer.ToArray());
        //        await encoder.FlushAsync();
        //    }
        //    isBusy = false;
        //}



        private async Task TakePhoto()
        {
            try
            {
                //StorageFolder picDir = KnownFolders.PicturesLibrary;
                // 新文件保存到本机相册中
                StorageFile newFile = await picDir.CreateFileAsync(
                    string.Format("{0}", HOW_OLD), CreationCollisionOption.OpenIfExists);

                if (newFile != null)
                {
                    // 开始捕捉
                    IsProcessingPicture = true;
                    InMemoryRandomAccessStream mmstream = new InMemoryRandomAccessStream();
                    var jpg = Windows.Media.MediaProperties.ImageEncodingProperties.CreateJpeg();
                    //jpg.Height = 400;
                    //jpg.Width = 800;
                    await capture.CapturePhotoToStreamAsync(jpg, mmstream);
                    mmstream.Seek(0); //将指针移到首位置
                    IRandomAccessStream outStream = await newFile.OpenAsync(FileAccessMode.ReadWrite);
                    // 对图像进行重编码
                    await EncodedPhoto(mmstream, outStream);
                    // 关闭流
                    mmstream.Dispose();
                    outStream.Dispose();
                    IsProcessingPicture = false;

                }
            }
            catch (Exception ex)
            {
            }
        }



        #region 处理图像
        private async Task EncodedPhoto(IRandomAccessStream inStream, IRandomAccessStream outStream)
        {
            // 解码器ID
            Guid JpegDecodderID = BitmapDecoder.JpegDecoderId;
            // 编码器ID
            Guid JpegEncoderID = BitmapEncoder.JpegEncoderId;

            BitmapDecoder decoder = await BitmapDecoder.CreateAsync(JpegDecodderID, inStream);
            // 取得像素数据
            byte[] data = (await decoder.GetPixelDataAsync()).DetachPixelData();

            // 创建编码器实例
            BitmapEncoder encoder = await BitmapEncoder.CreateAsync(JpegEncoderID, outStream);
            // 判断屏幕方向
            var orientation = SimpleOrientationSensor.GetDefault().GetCurrentOrientation();
            switch (orientation)
            {
                case SimpleOrientation.Rotated90DegreesCounterclockwise:
                    encoder.BitmapTransform.Rotation = BitmapRotation.None;
                    break;
                case SimpleOrientation.Rotated270DegreesCounterclockwise:
                    encoder.BitmapTransform.Rotation = BitmapRotation.Clockwise180Degrees;
                    break;
                case SimpleOrientation.NotRotated:
                    encoder.BitmapTransform.Rotation = BitmapRotation.Clockwise90Degrees;
                    break;
                case SimpleOrientation.Rotated180DegreesCounterclockwise:
                    encoder.BitmapTransform.Rotation = BitmapRotation.Clockwise270Degrees;
                    break;
            }
            // 设置像素数据
            encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Straight, decoder.PixelWidth, decoder.PixelHeight, decoder.DpiX, decoder.DpiY, data);

            //encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Premultiplied, 800, 480, 96, 96, data);

            await encoder.FlushAsync(); //将数据写入到流中
        }
        #endregion

        public static async Task SaveToFile(
    WriteableBitmap writeableBitmap,
   StorageFile outputFile)
        {
            Guid encoderId = BitmapEncoder.PngEncoderId;
            Stream stream = writeableBitmap.PixelBuffer.AsStream();
            byte[] pixels = new byte[(uint)stream.Length];
            await stream.ReadAsync(pixels, 0, pixels.Length);

            using (var writeStream = await outputFile.OpenAsync(FileAccessMode.ReadWrite))
            {
                var encoder = await BitmapEncoder.CreateAsync(encoderId, writeStream);
                encoder.SetPixelData(
                    BitmapPixelFormat.Bgra8,
                    BitmapAlphaMode.Premultiplied,
                    (uint)writeableBitmap.PixelWidth,
                    (uint)writeableBitmap.PixelHeight,
                    96,
                    96,
                    pixels);
                await encoder.FlushAsync();

                using (var outputStream = writeStream.GetOutputStreamAt(0))
                {
                    await outputStream.FlushAsync();
                }
            }
        }

        private async void Camera_Click(object sender, RoutedEventArgs e)
        {
            if (!isTapped)
            {
                return;
            }
            image.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
            await SetCaptureSourceAsync();
            isTapped = false;
        }

    }

    public class HowOldModel
    {
        public Thickness Margin { get; set; }

        public string Gander { get; set; }

        public int Age { get; set; }
    }


    public class HowOldResponse
    {
        public Analyticsevent[] AnalyticsEvent { get; set; }
        public Face1[] Faces { get; set; }
    }

    public class Analyticsevent
    {
        public Face face { get; set; }
        public DateTime event_datetime { get; set; }
        public string user_id { get; set; }
        public string session_id { get; set; }
        public string submission_method { get; set; }
        public object user_agent { get; set; }
        public Location location { get; set; }
        public Location_City location_city { get; set; }
        public bool is_mobile_device { get; set; }
        public string browser_type { get; set; }
        public string platform { get; set; }
        public string mobile_device_model { get; set; }
    }

    public class Face
    {
        public float age { get; set; }
        public string gender { get; set; }
    }

    public class Location
    {
        public float latitude { get; set; }
        public float longitude { get; set; }
    }

    public class Location_City
    {
        public float latitude { get; set; }
        public float longitude { get; set; }
    }

    public class Face1
    {
        public object faceId { get; set; }
        public Facerectangle faceRectangle { get; set; }
        public Attributes attributes { get; set; }
    }

    public class Facerectangle
    {
        public int top { get; set; }
        public int left { get; set; }
        public int width { get; set; }
        public int height { get; set; }
    }

    public class Attributes
    {
        public string gender { get; set; }
        public float age { get; set; }
    }


}
